import pygame, random, sys, os 
from pygame.locals import *

import tile, scenes, UIManager, constants

from UIManager import *
from constants import *
from scenes import *

playAgain = True
quit = False

class Game:
    """Represents one instance of the game. Glues all of our classes together in a way that makes sense. Performs initial Pygame setup and contains the main loop."""
    global playAgain, quit

    def __init__(self):
        """Creates an instance of the game"""
        print "Loading..."
        self.loadContent()
        self.mainLoop()
    
    def loadContent(self):
        """Performs initial game setup"""
        #the ConstantManager reads settings from settings.cfg and exposes them as constants
        self.constantManager = ConstantManager()

        #initialize Pygame so that we can do further setup
        pygame.init()
        self.clock = pygame.time.Clock()
        self.applySettings()
        self.mainSurface = pygame.display.set_mode(self.screenres)
        pygame.display.set_caption(self.constantManager.settings["TITLE"])


        self.showIntro()
        #now that pygame is initialized, instantiate the classes we'll need to show the map.
        self.demoScene = Scene(self.mainSurface)
        map = scenes.Map(self.demoScene)
        self.demoScene.addMap(map)
        self.demoScene.makeMapActive(map)
        self.demoScene.begin()

        #Here we'll load sounds and whatever else we happen to need. There'll probably be a wrapper
        #class created to make sound management easier
        print "Content load complete"

    def applySettings(self):
        """Runs at the beginning of loadContent. Gets settings from settings.cfg and applies them"""
        #This method runs at the beginning of loadContent
        #NOTHING in here can depend on content being loaded
        #instead, content loading should depend on settings loaded here
        res = self.constantManager.settings["SCREENRES"]
        self.width = int(res[0])
        self.height = int(res[1])
        self.screenres = (self.width, self.height)
        print "Settings applied"

    def showIntro(self):
        """Shows the game's intro screen"""
        enterFlasher = False
        ticks = 15
        bigFont = pygame.font.SysFont("Courier New", 32, bold=True)
        font = pygame.font.SysFont("Courier New", 14)

        self.bigFont = bigFont
        self.font = font

        nameLabel = Label(self.mainSurface, 0, 0, bigFont, "MISSION MARKOWSKY")
        subLabel = Label(self.mainSurface, 0, 40, font, "CAN YOU SURVIVE THE ACADEMIC WORLD?")
        explLabel = Label(self.mainSurface, 0, 80, font, "Your goal: to defeat the TAs defending Markowsky and then Markowsky himself!")
        expl2Label = Label(self.mainSurface, 0, 101, font, "Use the arrow keys to move and the Enter key to perform actions.")
        expl3Label = Label(self.mainSurface, 0, 122, font, "Run into TAs and Markowsky to engage in ACADEMIC COMBAT!")
        expl4Label = Label(self.mainSurface, 0, 144, font, "If your energy runs below 0, you lose!")
        expl5Label = Label(self.mainSurface, 0, 166, font, "Your GPA and energy combined effect how much damage you do.")

        enterLabel = Label(self.mainSurface, 0, 0, font, "Press enter to play!")
        enterLabel.y = (self.height - enterLabel.height)

        labels = [nameLabel, subLabel, explLabel, expl2Label, expl3Label, expl4Label, expl5Label, enterLabel]

        for label in labels:
            label.x = (self.width / 2) - (label.width / 2)
            label.drawSelf()    

        while True:
            ticks += 1

            if ticks > 15:
                enterLabel.drawSelf()
                enterFlasher = not enterFlasher
                ticks = 0

            if not enterFlasher:
                self.mainSurface.blit(enterLabel.calculateClearSurface(), (enterLabel.x, enterLabel.y))

            pygame.display.update()
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == KEYUP:
                    if event.key == K_RETURN:
                        self.mainSurface.fill((0, 0, 0))
                        self.width = ((TILESIZE * MAP_WIDTH) * 2) + 100
                        self.mainSurface = pygame.display.set_mode((self.width, self.height))
                        return
                    
            self.clock.tick(25)

    def showOutro(self):
        """Shows the game's outro screen"""
        self.mainSurface.fill((0, 0, 0))

        winLabel = Label(self.mainSurface, 0, 0, self.bigFont, "YOU WIN!")
        scoreLabel = Label(self.mainSurface, 0, 40, self.font, "Your score was: %d" % (self.demoScene.activeMap.player.points))
        playAgainLabel = Label(self.mainSurface, 0, 0, self.font, "Do you want to play again? (Y/N)")

        playAgainLabel.y = self.height - playAgainLabel.height

        labels = [winLabel, scoreLabel, playAgainLabel]

        for label in labels:
            label.x = (self.width / 2) - (label.width / 2)
            label.drawSelf()

        pygame.display.update()

        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == KEYUP:
                    if event.key == K_y:
                        return False
                    if event.key == K_n:
                        return True

    def mainLoop(self):
        """The main loop of the game"""
        self.demoScene.renderScene()
        pygame.display.update()
        self.demoScene.updateScene(pygame.event.wait())

        while True:
            if self.demoScene.hasWon:
                global quit
                quit = self.showOutro()
                return
            self.demoScene.renderScene()
            for event in pygame.event.get():
                if event.type == QUIT:
                    self.demoScene.end()
                    pygame.quit()
                    sys.exit()

                if event.type == KEYUP:
                    if self.demoScene.updateScene(event):
                        self.mainSurface.fill((0, 0, 0), self.demoScene.mapRect)
                        self.demoScene.renderScene()
                        pygame.display.update()
            self.clock.tick(30)
            
while playAgain:
    if quit:
        break
    Game()
